package com.ynet.middleground.approve.service.impl;

import java.util.List;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;

import com.google.common.base.Throwables;
import com.ynet.core.common.ServiceResult;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.middleground.approve.bean.ActivateProcessReq;
import com.ynet.middleground.approve.bean.DeleteProcessReq;
import com.ynet.middleground.approve.bean.DeployProcessReq;
import com.ynet.middleground.approve.bean.QueryProcessReqPager;
import com.ynet.middleground.approve.dto.ProcessDefinitionDTO;
import com.ynet.middleground.approve.model.ProcessModel;
import com.ynet.middleground.approve.service.ProcessDefinitionService;
import com.ynet.middleground.approve.utils.ErrorCodeUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * @author liulx
 * @description 流程定义相关接口服务实现类
 * @date 2019-10-09 22:26
 */
@Api(value = "流程定义相关接口服务", tags = {"流程定义相关接口服务"})
@Produces({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Consumes({MediaType.APPLICATION_JSON + "; " + "charset=UTF-8"})
@Path("definitions")
@Service(timeout = 6000, version = "0.0.1")
public class ProcessDefinitionServiceImpl implements ProcessDefinitionService {

    @Autowired
    private ProcessModel processModel;

    @Autowired
    private ErrorCodeUtil errorCodeUtil;

    /**
     * 部署流程 bpmn和png 压缩后的zip文件 <br />
     * TODO: 是否限制文件大小，及文件格式
     *
     * 
     * @param deployProcessReq 部署工作流规则文件对象: {文件流字节}
     * @return 部署ID
     */
    @POST
    @ApiOperation(value = "部署工作流文件（内管）", notes = "部署工作流规则文件，返回部署ID，供内管使用，渠道无需关心")
    @ApiImplicitParam(name = "requestObj", dataType = "DeployProcessReq", paramType = "body", required = true)
    @Override
    public ServiceResult<String> saveProcess(DeployProcessReq deployProcessReq) {
        ServiceResult<String> result = new ServiceResult<>();
        try {
            String deploymentId = processModel.saveProcess(deployProcessReq);
            result.setResult(deploymentId);
        } catch (Exception e) {
            IfpLogger.error("ProcessDefinitionServiceImpl.saveProcess", "activiti部署工作流文件异常，case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECAP0000", errorCodeUtil.getValue("ECAP0000"));
            return result;
        }
        return result;
    }

    /**
     * 根据流程部署ID删除流程
     *
     * @param deleteProcessReq 流程信息请求对象: {流程部署ID, 级联删除标志}
     * @return 删除结果标志，以success 字段值标识 true/false
     */
    @DELETE
    @ApiOperation(value = "删除流程定义（内管）", notes = "根据流程部署ID删除流程定义，流程定义是一个可具体使用的审批批流程，而并非流程实例，此接口供中台内管使用，渠道不需要关心")
    @ApiImplicitParam(name = "requestObj", dataType = "DeleteProcessReq", paramType = "body", required = true)
    @Override
    public ServiceResult removeProcessByDeploymentId(DeleteProcessReq deleteProcessReq) {
        ServiceResult<Object> result = new ServiceResult<>();
        try {
            processModel.removeProcessByDeploymentId(deleteProcessReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error("ProcessDefinitionServiceImpl.removeProcessByDeploymentId",
                "activiti根据流程部署ID删除流程异常，case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECAP0000", errorCodeUtil.getValue("ECAP0000"));
            return result;
        }
        result.setSuccess(true);
        return result;
    }

    /**
     * 分页查询流程定义列表
     *
     * @param reqPager 查询流程对象：{分页对象,流程名称}
     * @return 流程定义列表
     */
    @POST
    @Path("list")
    @ApiOperation(value = "查询流程定义列表", notes = "分页查询流程定义列表，返回审批中心目前所有绘制完成并可以使用的审批流程")
    @ApiImplicitParam(name = "requestObj", dataType = "QueryProcessReqPager", paramType = "body", required = true)
    @Override
    public ServiceResult<List<ProcessDefinitionDTO>> listProcessByPage(@RequestBody QueryProcessReqPager reqPager) {
        ServiceResult<List<ProcessDefinitionDTO>> result = new ServiceResult<>();
        try {
            List<ProcessDefinitionDTO> resultList = processModel.listProcessByPage(reqPager);
            result.setResult(resultList);
        } catch (Exception e) {
            IfpLogger.error("ProcessDefinitionServiceImpl.listProcessByPage", "activiti查询流程定义列表异常，case: {}",
                Throwables.getStackTraceAsString(e));
            result.setError("ECAP0000", errorCodeUtil.getValue("ECAP0000"));
            return result;
        }
        result.setPagerInfo(reqPager.getPagerInfo());
        result.setSuccess(true);
        return result;
    }

    /**
     * 挂起或激活指定流程定义
     *
     * @param processReq 激活流程对象: {流程定义id, 激活挂起标志}
     * @return 挂起或激活标志
     */
    @PUT
    @ApiOperation(value = "挂起或激活指定流程定义（内管）", notes = "挂起或激活指定流程定义，供中台内管使用，渠道不需要关心")
    @ApiImplicitParam(name = "requestObj", dataType = "ActivateProcessReq", paramType = "body", required = true)
    @Override
    public ServiceResult suspendOrActivateProcessDefinition(ActivateProcessReq processReq) {
        ServiceResult<Object> result = new ServiceResult<>();
        try {
            processModel.suspendOrActivateProcessDefinition(processReq);
        } catch (BusinessException be) {
            result.setError(be.getCode(), be.getMessage());
        } catch (Exception e) {
            IfpLogger.error("ProcessDefinitionServiceImpl.suspendOrActivateProcessDefinition",
                "activiti挂起或激活指定流程定义异常，case: {}", Throwables.getStackTraceAsString(e));
            result.setError("ECAP0000", errorCodeUtil.getValue("ECAP0000"));
            return result;
        }
        return result;
    }

}
